---@class WUltiity : Object
local WUltiity = {}

function WUltiity:getItemByRate(cfg,excepttb)
  excepttb = excepttb or {}
  local cnt = 0
  while true do
    cnt = cnt + 1
    local rand = math.random()
    local forward = 0
    for i, v in pairs(cfg) do
      local last = v.rate
      if rand >= forward and rand < last + forward and not excepttb[i] then
        return i
      end
      forward = forward + last
    end
    if cnt >= 50 then --小概率事件。避免死循环
      local properties = {}
      for i, v in pairs(cfg) do
        table.insert(properties,i)
      end
      return table.random(properties)
    end
  end
end

function WUltiity:getItemByWeight(cfg,excepttb)
  excepttb = excepttb or {}
  local cnt = 0
  while true do
    cnt = cnt + 1
    local rand = math.random()
    local forward = 0
    for i, v in pairs(cfg) do
      local last = v
      if rand >= forward and rand < last + forward and not excepttb[i] then
        return i
      end
      forward = forward + last
    end
    if cnt >= 50 then --避免死循环
      local properties = {}
      for i, v in pairs(cfg) do
        table.insert(properties,i)
      end
      return table.random(properties)
    end
  end
end

function WUltiity:getItemsByWeight(num,cfg)
  local tb = {}
  while #tb < num do
    local rand = math.random()
    local forward = 0
    for i, v in pairs(cfg) do
      local last = v
      if rand >= forward and rand < last + forward then
         table.insert(tb,i)      
        break
      end
      forward = forward + last
    end
  end
  return tb
end

function WUltiity:checkCards(player,pattern,num)
  local room = player.room
  local exp = Exppattern:Parse(pattern)
  local cards = {}
  for _, cid in ipairs(room.draw_pile) do
    local card = Fk:getCardById(cid)
    if exp:match(card) then
      table.insert(cards,cid)
    end
    if #cards >= num then break end
  end
  if #cards < num then
    for _, cid in ipairs(room.discard_pile) do
      local card = Fk:getCardById(cid)
      if exp:match(card) then
        table.insert(cards,cid)
      end
    end
  end
  if #cards > 0 then
    room:obtainCard(player, cards, true, fk.ReasonJustMove)
  end  
end

function WUltiity:removeSameItems(items,recitems)
  local removeSkill = function(item)
    for i,it in ipairs(recitems) do
      if it == item then
        return i
      end
    end
  end
  
  local removepos = {}
  for i,it in ipairs(items) do
    local ret = removeSkill(it)
    if ret then
      table.insert(removepos,ret)
    end
  end

  while #removepos > 0 do
    local curpos = table.remove(removepos,1)
    table.remove(recitems,curpos)
  end
end

function WUltiity:removeSameItemsByTB(items,recitems,property)
  local removeSkill = function(item)
    for i,tb in ipairs(recitems) do
      if tb[property] == item then
        return i
      end
    end
  end
  
  local removepos = {}
  for i,it in ipairs(items) do
    local ret = removeSkill(it)
    if ret then
      table.insert(removepos,ret)
    end
  end

  while #removepos > 0 do
    local curpos = table.remove(removepos,1)
    table.remove(recitems,curpos)
  end
end

function WUltiity:getPlayerSkills(player)
  local skills = {}
  for _,s in ipairs(player.player_skills) do
    if s.frequency < Skill.Compulsory and not s.attached_equip then
      table.insert(skills,s.name)
    end
  end
  return skills
end

function WUltiity:getRandItemsByTB(rectb,num)
  local tb = {}
  for i=1,num do
    local item = self:getRandItemByTB(rectb)
    table.insert(tb,item)
  end
  return tb
end

function WUltiity:getRandItemByTB(rectb)
  return table.remove(rectb,math.random(1,#rectb))
end

return WUltiity